import argparse
from ipaddress import ip_address
from operator import le
import os
from xmlrpc.client import FastParser
import pandas as pd
import ast

parser = argparse.ArgumentParser()

parser.add_argument('--path', type=str, default=str('/home/zhangye/hejl/Dynaminc_Graphsage_Hypergraph_convolution/graphsage/parameter_common_dim.txt'), help='input batch size')
parser.add_argument('--begin', type=str, default=str('false'), help='input batch size')
parser.add_argument('--max_proc', type=int, default=2, help='input batch size')
parser.add_argument('--exec_proc', type=str, default=str('Hepergraph_convolution_main.py'), help='input batch size')
parser.add_argument('--para_file', type=str, default=str('nd_adjust_parameter.csv'))
parser.add_argument('--one_device_nums', type=int, default=1, help='input batch size')
parser.add_argument('--update_adjust_parameter', type=str, default=str('false'), help='input batch size')
opt = parser.parse_args()

# pars = [['common_dim', 256, 512, 1024, 2048], ['model', 'mean', 'maxpool', 'gcn', 'seq'], ['lr', 0.1, 0.01, 0.001], ['num_global_layer', 2, 3, 4]]
pars = [['msepara', 1, 10, 100], ['maepara', 1, 10, 100], ['mu', 1, 10, 100], ['embedding_dim', 50, 100,150, 200], ['lr', 0.001, 0.01, 0.1], ['reward_type', 1, 2, 3], ['state_type', 1, 2]]
host_python_path = ['/home/n40/anaconda3/envs/pytorch1.12/bin/python', '/home/a41/anaconda3/envs/pytorch1.12/bin/python', '/home/s44/anaconda3/envs/pytorch1.12/bin/python', '/home/a48/anaconda3/envs/pytorch/bin/python']
exec_python_path = ['/home/n40/code/aesthetic_path/AL_MRL', '/home/a41/AL_MRL', '/home/s44/AL_MRL', '/home/a48/code/AL_MRL']
host_names = ['n40', 'a41', 's44', 'a48']
# file_extension = os.path.splitext(opt.para_file)[1]
# if file_extension == str('.txt'):
#     # pars = []
#     with open(opt.para_file, mode='r', encoding='utf-8') as file:
#         lines = file.readlines()
#         for line in lines:
#             one_row = line.strip().split()
#             pars.append(one_row)
# elif file_extension == str('.csv'):
#     df = pd.read_csv(opt.para_file, header=None, dtype=str)
#     df = df.fillna('empty')
#     for idx, line in df.iterrows():
#         line = line.values.tolist()
#         one_row = []
#         for va in line:
#             if va != str('empty'):
#                 one_row.append(va)
#         pars.append(one_row)
# else:
#     raise ValueError("para_file error")

def compare_evaluate_result(left, right):
    lmae, lmse, lrmse, rmae, rmse, rrmse = left[0], left[1], left[-1], right[0], right[1], right[-1]
    if lmse < rmse:
        if lmae < rmae:
            return True
        else:
            if rmse - lmse >= lmae - rmae:
                return True
            else:
                return False
    else:
        if lmae > rmae:
            return False
        else:
            if lmse - rmse >= rmae - lmae:
                return False
            else: 
                return True

    # if left[-2][-1] > right[-2][-1]:
    #     return True
    # elif left[-2][-1] == right[-2][-1]:
    #     if left[-1][-1] > right[-1][-1]:
    #         return True
    #     elif left[-1][-1] == right[-1][-1]:
    #         if left[-3][-1] > right[-3][-1]:
    #             return True
    # return False 

lr_res, pos, ans = [], -1, str('')
if opt.begin == str('false'):
    with open(opt.path, mode='r', encoding='utf-8') as file:
        lines = file.readlines()
        for line in lines:
            line = line.strip()
            fname, name, val = line.split(' ', 2)
            # val = float(val)
            val = ast.literal_eval(val)
            lr_res.append([fname, name, val])
    print(f'lr_res is {lr_res}')
    print(f'opt.path is {opt.path}')
    F_name, final_name, temp = lr_res[0][0], lr_res[0][1], lr_res[0][-1]
    for _ in lr_res:
        ###定义评价指标比较规则###
        if compare_evaluate_result(_[2], temp):
            final_name = _[1]
            temp = _[2]
    #

    ans = str(' --') + F_name + str(' ') + final_name
    if opt.update_adjust_parameter == str('true'):
        with open('adjust_add_par.txt', mode='a', encoding='utf-8') as file:
            file.write(ans)

        with open('adjust_add_par.txt', mode='r', encoding='utf-8') as file:
            ans = file.readline()

    for _ in range(len(pars)):
        if F_name == pars[_][0]:
            pos = _

def get_ip(host_name):
    os.system(f'scp zhangye@10.68.136.130:/home/zhangye/{host_name}_ip.txt ./')
    ip_add = None
    with open(f'{host_name}_ip.txt', mode='r', encoding='utf-8') as file:
        ip_add = file.read().strip()
    return ip_add
if pos < int(len(pars) - 1):
    next_F_name = pars[pos + 1][0]
    write_path = str('run_par_') + next_F_name + str('.sh')
    if os.path.exists(write_path):
        os.remove(write_path)
    with open(write_path, mode='a', encoding='utf-8') as file:
        for _ in range(1, len(pars[pos + 1]), 1):
            if _ == 1:
                exec_str = str(f'python {opt.exec_proc} {ans} --is_adjust_paramete true --Set_data true --{next_F_name} {pars[pos + 1][_]} --expand_name {next_F_name} --CNN_USE_TRANSFORM true &')
            else:
                ip_address = get_ip(host_names[_ - 1])
                exec_str = str(f'ssh {host_names[_ - 1]}@{ip_address} \'{host_python_path[_ - 1]} {exec_python_path[_ - 1]}/{opt.exec_proc} {ans} --is_adjust_paramete true --Set_data true --CNN_USE_TRANSFORM true --{next_F_name} {pars[pos + 1][_]} --expand_name {next_F_name} \' &')
            file.write(exec_str)
            file.write('\n')
        file.write(str('wait\n'))
        for _ in range(2, len(pars[pos + 1]), 1):
            ip_address = get_ip(host_names[_ - 1])
            # file.write(str(f'cat {host_names[_ - 1]}@{ip_address}:{exec_python_path[_ - 1]}/parameter_{next_F_name}.txt >> zhangye@10.68.136.130:/home/zhangye/parameter_{next_F_name}.txt'))
            file.write(str(f'ssh {host_names[_ - 1]}@{ip_address}  \'cat {exec_python_path[_ - 1]}/parameter_{next_F_name}.txt\' | ssh zhangye@10.68.136.130 \'cat >>  /home/zhangye/parameter_{next_F_name}.txt\''))
            file.write('\n')
        file.write('wait\n')
        file.write(str(f'ssh zhangye@10.68.136.130 \'cat /home/zhangye/parameter_{next_F_name}.txt\' >> parameter_{next_F_name}.txt'))
        # file.write(str(f'scp zhangye@10.68.136.130:/home/zhangye/parameter_{next_F_name}.txt {exec_python_path[0]}/'))
        file.write('\n')
        file.write(str('wait\n'))
        result_save_path = str('parameter_') + next_F_name + str('.txt')
        exec_command = str('python parallel_adjust_parameter_bash.py --path ') + str(result_save_path) + str(f' --exec_proc {opt.exec_proc} ')
        # exec_command = exec_command + str(f'--max_proc {opt.max_proc} --one_device_nums {opt.one_device_nums}\n')
        file.write(exec_command)
    os.system(f'chmod +x {write_path}')
    os.system(f'bash {write_path}')

if pos == int(len(pars) - 1):
    adjust_para_result_path = str('adjust_para_result.txt')
    first_row = str('默认参数: ')
    with open(adjust_para_result_path, mode='a', encoding='utf-8') as wr:
        os.system(f'cat adjust_add_par.txt | xargs -I{{}} echo "默认参数 {{}}" >> {adjust_para_result_path}')
        os.remove('adjust_add_par.txt')
        for _ in range(len(pars)):
            para_name = pars[_][0]
            os.system(f'cat parameter_{para_name}.txt >> {adjust_para_result_path}')
            os.remove(f'parameter_{para_name}.txt')
            os.remove(f'run_par_{para_name}.sh')